package com.czg.jsonschema2lombokpojo.annotator;

import com.czg.jsonschema2lombokpojo.config.GenerationConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JDefinedClass;
import org.apache.commons.lang.StringUtils;

/**
 * @author czg
 */
public abstract class AbstractTypeInfoAwareAnnotator extends AbstractAnnotator {
    public AbstractTypeInfoAwareAnnotator(GenerationConfig generationConfig) {
        super(generationConfig);
    }

    @Override
    public void typeInfo(JDefinedClass clazz, JsonNode node, boolean isEnum) {
        if(isEnum){
            if (getGenerationConfig().isEnumIncludeAllArgsConstructor()) {
                clazz.annotate(lombok.AllArgsConstructor.class);
            }
            if (getGenerationConfig().isEnumIncludeGetter()) {
                clazz.annotate(lombok.Getter.class);
            }
        }else {
            clazz.annotate(lombok.Data.class);
            if (getGenerationConfig().isIncludeEqualsAndHashCode()) {
                clazz.annotate(lombok.EqualsAndHashCode.class).param("callSuper", true);
            }
            if (getGenerationConfig().isIncludeNoArgsConstructor()) {
                clazz.annotate(lombok.NoArgsConstructor.class);
            }
            if (getGenerationConfig().isIncludeAllArgsConstructor()) {
                clazz.annotate(lombok.AllArgsConstructor.class);
            }
            if (getGenerationConfig().isIncludeBuilder()) {
                clazz.annotate(lombok.Builder.class);
            }
            if (getGenerationConfig().isFieldNameConstants()) {
                clazz.annotate(lombok.experimental.FieldNameConstants.class);
            }
            if (getGenerationConfig().isIncludeAccessors()) {
                JAnnotationUse jAnnotationUse = clazz.annotate(lombok.experimental.Accessors.class);
                jAnnotationUse.param("fluent", getGenerationConfig().getAccessorsFluentValue());
                jAnnotationUse.param("chain", getGenerationConfig().getAccessorsChainValue());
                if (StringUtils.isNotBlank(getGenerationConfig().getAccessorsPrefix())) {
                    jAnnotationUse.param("prefix", getGenerationConfig().getAccessorsPrefix());
                }
            }
        }

        /*

        if (getGenerationConfig().isIncludeTypeInfo()) {
            // Have per-schema JavaTypeInfo configuration override what is defined in generation config; backward comparability
            if (node.has("deserializationClassProperty")) {
                String annotationName = node.get("deserializationClassProperty").asText();
                addJsonTypeInfoAnnotation(clazz, annotationName);
            } else {
                addJsonTypeInfoAnnotation(clazz, "@class");
            }
        } else {
            // per-schema JsonTypeInfo configuration
            if (node.has("deserializationClassProperty")) {
                String annotationName = node.get("deserializationClassProperty").asText();
                addJsonTypeInfoAnnotation(clazz, annotationName);
            }
        }
         */
    }

    @Override
    public boolean isPolymorphicDeserializationSupported(JsonNode node) {
        return node.has("deserializationClassProperty");
    }

    abstract protected void addJsonTypeInfoAnnotation(JDefinedClass clazz, String propertyName);
}
